/*
 * MemoryLockManager.java
 * Created on 2006-12-5
 *
 * @Description: com.bearingpoint.hr.payroll.piinterface.domain.importer
 */
package com.mycompany.app.hr.common.mutexlock.memory;

import java.util.HashMap;
import java.util.Map;
import com.mycompany.app.hr.common.mutexlock.FailedAcquireLockException;
import com.mycompany.app.hr.common.mutexlock.IMutexLockManager;

/**
 * @author martin.liu
 * @version: 0.9, 2006-12-5
 * @Description: MemoryLockManager 1.Implement the lock manager within
 *               memory/jvm scope can't work in the cluster environment. 2.The
 *               lock manager is thread-safe and can work in concurrent
 *               environment. TODO list: 1.Check whether locked by the same
 *               token. If yes, re-acquire the lock again. 2.Implement the lock
 *               manager with some pooling mechanism.
 */
public class MemoryLockManager implements IMutexLockManager {
    private static final org.apache.commons.logging.Log log = org.apache.commons.logging.LogFactory
            .getLog(MemoryLockManager.class);

    @SuppressWarnings("unchecked")
    private static Map LOCK_POOL = new HashMap(20);

    /*
     * (non-Javadoc)
     * 
     * @see com.bearingpoint.hr.payroll.piinterface.domain.importer.support.ILockManager#isLock(java.lang.Object)
     */
    public boolean isLock(Object token) {

        if (LOCK_POOL.get(token) == null)
            return false;

        return true;
    }

    private Object queryLockToken(Object token) {

        return LOCK_POOL.get(token);
    }

    /*
     * (non-Javadoc)
     * 
     * @see com.bearingpoint.hr.payroll.piinterface.domain.importer.support.ILockManager#acquireLock(java.lang.Object)
     */
    @SuppressWarnings("unchecked")
    synchronized public void acquireLock(Object token)
            throws IllegalStateException {

        if (isLock(token)) {
            String msg = "Lock for " + token + " has be taken by "
                    + queryLockToken(token);
            log.warn(msg);
            throw new FailedAcquireLockException(msg);
        }

        LOCK_POOL.put(token, token);
        log.info("Acquire lock for " + token.toString());
    }

    /*
     * (non-Javadoc)
     * 
     * @see com.bearingpoint.hr.payroll.piinterface.domain.importer.support.ILockManager#releaseLock(java.lang.Object)
     */
    synchronized public void releaseLock(Object token) {

        if (!isLock(token)) {
            log.warn("Fail to release unused lock.");
            return;
        }

        LOCK_POOL.remove(token);
        log.info("Release lock for " + token.toString());
    }
}